import { Service } from '../types/index.js';

/**
 * API服务
 * 负责统一处理HTTP请求，包括拦截器、错误处理、认证等
 */
class ApiService extends Service {
  constructor(container) {
    super(container);
    
    // 获取配置
    this.apiConfig = container.getConfig('admin.api', {
      baseUrl: '/api',
      timeout: 30000,
      retryCount: 0,
      showLoading: true,
      loadingDelay: 300
    });
    
    // 获取认证服务
    this.authService = null;
    
    // 计数器，用于跟踪并发请求
    this.requestCount = 0;
    
    // 重试配置
    this.retryableStatusCodes = [408, 429, 500, 502, 503, 504];
    
    // 初始化axios实例
    this.http = this.createHttpInstance();
    
    // 初始化拦截器
    this.setupInterceptors();
  }

  /**
   * 创建HTTP实例
   * 注：这里使用fetch API作为基础，也可以替换为axios
   */
  createHttpInstance() {
    const http = {
      // 基础请求方法
      async request(config) {
        const mergedConfig = {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json'
          },
          timeout: this.apiConfig.timeout,
          ...config
        };

        // 处理URL
        if (!mergedConfig.url.startsWith('http')) {
          mergedConfig.url = `${this.apiConfig.baseUrl}${mergedConfig.url}`;
        }

        // 处理请求体
        if (mergedConfig.data && !(mergedConfig.data instanceof FormData)) {
          mergedConfig.data = JSON.stringify(mergedConfig.data);
        }

        return this.sendRequest(mergedConfig);
      },

      // GET请求
      get(url, params, config = {}) {
        return this.request({
          ...config,
          method: 'GET',
          url,
          params
        });
      },

      // POST请求
      post(url, data, config = {}) {
        return this.request({
          ...config,
          method: 'POST',
          url,
          data
        });
      },

      // PUT请求
      put(url, data, config = {}) {
        return this.request({
          ...config,
          method: 'PUT',
          url,
          data
        });
      },

      // DELETE请求
      delete(url, params, config = {}) {
        return this.request({
          ...config,
          method: 'DELETE',
          url,
          params
        });
      },

      // PATCH请求
      patch(url, data, config = {}) {
        return this.request({
          ...config,
          method: 'PATCH',
          url,
          data
        });
      },

      // 上传文件
      upload(url, formData, config = {}) {
        return this.request({
          ...config,
          method: 'POST',
          url,
          data: formData,
          headers: {
            'Content-Type': 'multipart/form-data',
            ...config.headers
          }
        });
      },

      // 下载文件
      download(url, params, config = {}) {
        return this.request({
          ...config,
          method: 'GET',
          url,
          params,
          responseType: 'blob'
        });
      }
    };

    // 绑定this上下文
    Object.keys(http).forEach(key => {
      if (typeof http[key] === 'function') {
        http[key] = http[key].bind(this);
      }
    });

    return http;
  }

  /**
   * 发送请求并处理重试
   */
  async sendRequest(config, retryCount = 0) {
    // 显示加载状态
    if (config.showLoading !== false && this.apiConfig.showLoading) {
      this.showLoading();
    }

    try {
      // 处理查询参数
      let url = config.url;
      if (config.params) {
        const queryString = this.buildQueryString(config.params);
        url += (url.includes('?') ? '&' : '?') + queryString;
      }

      // 创建AbortController用于超时控制
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), config.timeout);

      // 发送请求
      const response = await fetch(url, {
        ...config,
        headers: config.headers,
        signal: controller.signal
      });

      // 清除超时定时器
      clearTimeout(timeoutId);

      // 处理响应
      if (config.responseType === 'blob') {
        const blob = await response.blob();
        return this.handleBlobResponse(blob, response);
      } else {
        const data = await response.json();
        return this.handleJsonResponse(response, data);
      }
    } catch (error) {
      // 处理错误
      if (error.name === 'AbortError') {
        throw new Error('Request timeout');
      }

      // 处理重试逻辑
      if (retryCount < this.apiConfig.retryCount && this.isRetryableError(error)) {
        retryCount++;
        console.log(`Retrying request (${retryCount}/${this.apiConfig.retryCount})...`);
        // 指数退避策略
        const delay = Math.pow(2, retryCount - 1) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
        return this.sendRequest(config, retryCount);
      }

      throw error;
    } finally {
      // 隐藏加载状态
      if (config.showLoading !== false && this.apiConfig.showLoading) {
        this.hideLoading();
      }
    }
  }

  /**
   * 构建查询字符串
   */
  buildQueryString(params) {
    return Object.keys(params)
      .filter(key => params[key] !== undefined && params[key] !== null)
      .map(key => {
        const value = params[key];
        if (Array.isArray(value)) {
          return value.map(val => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join('&');
        }
        return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
      })
      .join('&');
  }

  /**
   * 处理JSON响应
   */
  handleJsonResponse(response, data) {
    // 统一的业务错误处理
    if (!response.ok) {
      // 根据HTTP状态码处理
      switch (response.status) {
        case 401:
          // 未授权，可能需要重新登录
          this.handleUnauthorized();
          break;
        case 403:
          throw new Error('Permission denied');
        case 404:
          throw new Error('Resource not found');
        default:
          throw new Error(data.message || `HTTP Error: ${response.status}`);
      }
    }

    // 业务逻辑错误处理（假设后端返回{code, message, data}结构）
    if (data.code && data.code !== 200) {
      throw new Error(data.message || 'Business logic error');
    }

    return data;
  }

  /**
   * 处理Blob响应（文件下载）
   */
  handleBlobResponse(blob, response) {
    // 从响应头获取文件名
    const contentDisposition = response.headers.get('content-disposition');
    let filename = 'download';
    
    if (contentDisposition) {
      const match = contentDisposition.match(/filename="?([^;"]+)"?/);
      if (match && match[1]) {
        filename = decodeURIComponent(match[1]);
      }
    }

    // 创建下载链接
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    
    // 清理
    setTimeout(() => {
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    }, 100);

    return { success: true, filename };
  }

  /**
   * 设置拦截器
   */
  setupInterceptors() {
    // 请求拦截器（这里通过重写request方法实现）
    const originalRequest = this.http.request;
    this.http.request = async (config) => {
      // 前置处理
      config = await this.beforeRequest(config);
      
      try {
        // 执行原始请求
        return await originalRequest.call(this.http, config);
      } catch (error) {
        // 错误处理
        return this.handleError(error, config);
      }
    };
  }

  /**
   * 请求前处理
   */
  async beforeRequest(config) {
    // 确保authService已初始化
    if (!this.authService) {
      this.authService = this.container.get('auth');
    }

    // 添加认证token
    if (this.authService && this.authService.isLoggedIn()) {
      const token = this.authService.getToken();
      if (token) {
        config.headers = {
          ...config.headers,
          'Authorization': `Bearer ${token}`
        };
      }
    }

    // 添加时间戳防止缓存
    if (config.method === 'GET') {
      config.params = {
        ...config.params,
        _t: Date.now()
      };
    }

    return config;
  }

  /**
   * 错误处理
   */
  async handleError(error, config) {
    // 记录错误日志
    console.error('API Request Error:', error);

    // 根据错误类型处理
    if (error.message === 'Request timeout') {
      // 超时错误
      this.showError('请求超时，请检查网络连接');
    } else if (error.message === 'Network error') {
      // 网络错误
      this.showError('网络错误，请检查网络连接');
    } else if (error.message.includes('401')) {
      // 未授权错误
      this.handleUnauthorized();
    } else {
      // 其他错误
      this.showError(error.message || '请求失败');
    }

    throw error; // 重新抛出错误以便上层处理
  }

  /**
   * 处理未授权错误
   */
  handleUnauthorized() {
    // 清除登录状态并重定向到登录页面
    if (this.authService) {
      this.authService.logout(true);
    }
  }

  /**
   * 检查错误是否可重试
   */
  isRetryableError(error) {
    // 检查是否是网络错误或服务器错误
    return !error.response || (error.response && 
      this.retryableStatusCodes.includes(error.response.status));
  }

  /**
   * 显示加载状态
   */
  showLoading() {
    this.requestCount++;
    
    // 使用延迟显示，避免频繁切换
    if (this.requestCount === 1) {
      this.loadingTimer = setTimeout(() => {
        // 这里可以触发全局loading事件或调用UI组件
        this.emit('loading', true);
      }, this.apiConfig.loadingDelay);
    }
  }

  /**
   * 隐藏加载状态
   */
  hideLoading() {
    this.requestCount--;
    
    if (this.requestCount <= 0) {
      this.requestCount = 0;
      
      // 清除定时器
      if (this.loadingTimer) {
        clearTimeout(this.loadingTimer);
        this.loadingTimer = null;
      }
      
      // 隐藏loading
      this.emit('loading', false);
    }
  }

  /**
   * 显示错误信息
   */
  showError(message) {
    // 这里可以集成通知服务或直接使用alert
    console.error(message);
    
    // 如果有通知服务，使用通知服务显示错误
    try {
      const notificationService = this.container.get('notification');
      if (notificationService && notificationService.error) {
        notificationService.error(message);
      } else {
        alert(message);
      }
    } catch (e) {
      // 降级到alert
      alert(message);
    }
  }

  /**
   * 批量请求
   */
  async batchRequests(requests) {
    try {
      const results = await Promise.all(requests);
      return results;
    } catch (error) {
      console.error('Batch request failed:', error);
      throw error;
    }
  }

  /**
   * 串行请求
   */
  async serialRequests(requests) {
    const results = [];
    
    for (const request of requests) {
      try {
        const result = await request();
        results.push(result);
      } catch (error) {
        console.error('Serial request failed:', error);
        throw error;
      }
    }
    
    return results;
  }

  /**
   * 缓存请求结果
   */
  async cachedRequest(key, requestFn, ttl = 5 * 60 * 1000) { // 默认缓存5分钟
    // 简单内存缓存实现
    const cacheKey = `api_cache_${key}`;
    
    // 检查缓存
    if (this.cache && this.cache[cacheKey]) {
      const cached = this.cache[cacheKey];
      if (Date.now() < cached.expireTime) {
        return cached.data;
      }
    }

    // 执行请求
    const data = await requestFn();
    
    // 存入缓存
    if (!this.cache) {
      this.cache = {};
    }
    
    this.cache[cacheKey] = {
      data,
      expireTime: Date.now() + ttl
    };
    
    return data;
  }

  /**
   * 清除缓存
   */
  clearCache(key) {
    if (!this.cache) return;
    
    if (key) {
      // 清除指定缓存
      delete this.cache[`api_cache_${key}`];
    } else {
      // 清除所有缓存
      this.cache = {};
    }
  }

  /**
   * 启动服务
   */
  boot() {
    console.log('ApiService booted');
    // 初始化缓存
    this.cache = {};
  }

  /**
   * 关闭服务
   */
  shutdown() {
    console.log('ApiService shutdown');
    // 清除缓存
    this.clearCache();
    // 清除定时器
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer);
    }
  }
}

export default ApiService;